<?php

namespace app\oauth\library;

use League\OAuth2\Server\AuthorizationServer; //授权服务器启动类

use League\OAuth2\Server\Grant\AuthCodeGrant; //授权码模式
use League\OAuth2\Server\Grant\ImplicitGrant; //隐式授权模式
use League\OAuth2\Server\Grant\ClientCredentialsGrant; //客户端模式
use League\OAuth2\Server\Grant\PasswordGrant; //密码模式
use League\OAuth2\Server\Grant\RefreshTokenGrant; //刷新令牌

use League\OAuth2\Server\Exception\OAuthServerException; //异常

use app\oauth\Repositories\ClientRepository;
use app\oauth\Repositories\AccessTokenRepository;
use app\oauth\Repositories\AuthCodeRepository;
use app\oauth\Repositories\RefreshTokenRepository;
use app\oauth\Repositories\ScopeRepository;
use app\oauth\Repositories\UserRepository;




class OauthServer
{
    protected $server;


    public function __construct()
    {
        $clientRepository = new ClientRepository();
        $accessTokenRepository = new AccessTokenRepository();
        $authCodeRepository = new AuthCodeRepository();
        $refreshTokenRepository = new RefreshTokenRepository();
        $scopeRepository = new ScopeRepository();
        $userRepository = new UserRepository();

        $privateKeyPath = file_get_contents(app()->getRootPath() . 'app/oauth/config/key/private.key');
        $encryptionKeyPath = file_get_contents(app()->getRootPath() . 'app/oauth/config/key/public.key');

        $server = new AuthorizationServer(
            $clientRepository,
            $accessTokenRepository,
            $scopeRepository,
            $privateKeyPath,
            $encryptionKeyPath
        );

        $this->server = $server;


        $this->server->enableGrantType(
            $this->authCodeGrant(),
            new \DateInterval('PT1H') // 设置访问令牌过期时间1小时
        );

        $this->server->enableGrantType(
            $this->refreshTokenGrant(),
            new \DateInterval('PT1H') // 设置访问令牌过期时间1小时
        );

        $this->server->enableGrantType(
            $this->passwordGrant(),
            new \DateInterval('PT1H') // 设置访问令牌过期时间1小时
        );

        $this->server->enableGrantType(
            new ClientCredentialsGrant(),
            new \DateInterval('PT1H') // 设置访问令牌过期时间1小时
        );

        $this->server->enableGrantType(
            $this->implicitGrant(),
            // new \DateInterval('PT1H') // 设置访问令牌过期时间1小时
        );
    }


    //授权码模式
    protected function authCodeGrant()
    {
        return new AuthCodeGrant(
            new AuthCodeRepository(),
            new RefreshTokenRepository(),
            new \DateInterval('PT10M') // 设置授权码过期时间为10分钟
        );
    }

    //刷新令牌
    protected function refreshTokenGrant()
    {
        $grant =  new RefreshTokenGrant(new RefreshTokenRepository());

        $grant->setRefreshTokenTTL(new \DateInterval('PT10M'));

        return $grant;
    }


    //密码模式
    protected function passwordGrant()
    {
        $grant = new PasswordGrant(
            new UserRepository(),
            new RefreshTokenRepository()
        );

        $grant->setRefreshTokenTTL(new \DateInterval('PT10M'));

        return $grant;
    }

    //隐匿模式
    protected function implicitGrant()
    {
        return new ImplicitGrant(new \DateInterval('PT10M'));
    }


    public function respondToAccessTokenRequest($request, $response)
    {
        return $this->server->respondToAccessTokenRequest($request, $response);
    }


    public function validateAuthorizationRequest($request)
    {
        return $this->server->validateAuthorizationRequest($request);
    }
    
    public function completeAuthorizationRequest($authRequest, $response)
    {
        return $this->server->completeAuthorizationRequest($authRequest, $response);
    }
}
